home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / netBoot.new / dev / xy.c < prev    next >
C/C++ Source or Header  |  1990-12-19  |  8KB  |  323 lines

  1.  
  2. #ifndef lint
  3. /* static  char sccsid[] = "@(#)xy.c 1.1 86/09/27 Copyr 1986 Sun Micro"; */
  4. #endif
  5.  
  6. /*
  7.  * Copyright (c) 1986 by Sun Microsystems, Inc.
  8.  */
  9.  
  10. /* Standalone driver for Xylogics 440/450 */
  11.  
  12. #ifndef M25
  13. #include "../dev/saio.h"
  14. #include "../h/param.h"
  15. #include "../dev/dkbad.h"
  16. #include "../dev/dklabel.h"
  17. #include "../dev/dkio.h"
  18. #include "../h/fsdir.h"
  19. #include "../dev/xycreg.h"
  20. #include "../dev/xyreg.h"
  21.  
  22.  
  23. extern char    msg_nolabel[];
  24.  
  25. struct xyparam {
  26.     unsigned short    xy_boff;    /* Cyl # starting partition */
  27.      unsigned short    xy_nsect;    /* Sect/track */
  28.      unsigned short    xy_ncyl;    /* Cyl/disk */
  29.      unsigned short    xy_nhead;    /* Heads/cyl */
  30.      unsigned short    xy_bhead;    /* Base head # for removable disk */
  31.      unsigned short    xy_drive;    /* Xylogics drive type ID */
  32.     int    xy_nblk;
  33.     int    xy_badaddr;        /* Disk block # of bad-block table */
  34.     struct dkbad xy_bad;
  35.     unsigned char    xy_unit;
  36. };
  37.  
  38. #define CYL(p)  (p*xyp->xy_nsect*xyp->xy_nhead)     /* cyl to block conv */
  39.  
  40. #define NSTD     2
  41. #define MAXBSIZE        8192
  42. unsigned long xystd[NSTD] = { 0xee40, 0xee48 };
  43.  
  44. /*
  45.  * Structure of our DMA area
  46.  */
  47. struct xydma {
  48.     struct xyiopb    xyiopb;
  49.     char        xyblock[MAXBSIZE];    /* R/W data */
  50. };
  51.  
  52. /*
  53.  * What resources we need to run
  54.  */
  55. struct devinfo xyinfo = {
  56.     sizeof (struct xydevice), 
  57.     sizeof (struct xydma),
  58.     sizeof (struct xyparam),
  59.     NSTD,
  60.     xystd,
  61.     MAP_MBIO,
  62. #ifdef BOOTBLOCK
  63.     DEV_BSIZE,
  64. #else
  65.     DEV_BSIZE,    /* MAXBSIZE, */
  66. #endif
  67. };
  68.  
  69. /*
  70.  * What facilities we export to the world
  71.  */
  72. int    xyopen(), xystrategy();
  73. extern int    xxboot(), xxprobe();
  74. extern int    nullsys();
  75.  
  76. struct boottab xydriver = {
  77.     "xy",    xxprobe, xxboot, xyopen, nullsys, xystrategy,
  78.     "xy: Xylogics 440/450 disk", &xyinfo,
  79. }; 
  80.  
  81.  
  82. /*
  83.  * Open a xylogics disk.
  84.  */
  85. xyopen(sip)
  86.     register struct saioreq *sip;
  87. {
  88.     register struct xyparam *xyp;
  89.     register struct xydevice *xyaddr;
  90.     register struct xyiopb *xy;
  91.     struct dk_label *label;
  92.     register int i, t;
  93.     u_short ppart;
  94. #ifndef BOOTBLOCK
  95.     int xyspin();
  96. #endif !BOOTBLOCK
  97.  
  98.     xyp = (struct xyparam *)sip->si_devdata;
  99.     xyaddr = (struct xydevice *)sip->si_devaddr;
  100.     xy = &((struct xydma *)sip->si_dmaaddr)->xyiopb;
  101.  
  102.     xyp->xy_unit = sip->si_unit & 0x03;
  103.     ppart = (sip->si_unit >> 2) & 1;
  104.  
  105.     /* reset controller */
  106.     i = xyaddr->xy_resupd;
  107. #ifdef lint
  108.     i = i;        /* Avoid complaint about "set but not used" */
  109. #endif
  110.     DELAY(100);    /* Allow for controller recovery time */
  111.  
  112.     xyp->xy_boff  = 0;        /* Don't offset block numbers */
  113.     xyp->xy_nsect = 2;
  114.     xyp->xy_nhead = 2;
  115.     xyp->xy_ncyl = 2;
  116.     xyp->xy_bad.bt_mbz = -1;
  117.  
  118. #ifndef BOOTBLOCK
  119.     /*
  120.      * Wait for disk to spin up, if necessary.
  121.      */
  122.     if (!isspinning(xyspin, (char *)sip, 0))
  123.         return (-1);
  124. #endif !BOOTBLOCK
  125.  
  126.     for (xyp->xy_drive = 0; xyp->xy_drive < NXYDRIVE; xyp->xy_drive++) {
  127.         label = (struct dk_label *)
  128.             ((struct xydma *)sip->si_dmaaddr)->xyblock;
  129.         label->dkl_magic = 0;
  130.         if (xycmd(XY_READ, sip, 0, (char *)label, 1))
  131.             continue;
  132.         if (chklabel(label))
  133.             continue;
  134.         if (ppart != label->dkl_ppart)
  135.             continue;
  136.         goto foundlabel;
  137.     }
  138.     printf(msg_nolabel);
  139.     return (-1);
  140.  
  141. foundlabel:
  142.     xyp->xy_nhead = label->dkl_nhead;
  143.     xyp->xy_nsect = label->dkl_nsect;
  144.     xyp->xy_ncyl  = label->dkl_ncyl + label->dkl_acyl;
  145.     xyp->xy_boff  = label->dkl_map[sip->si_boff].dkl_cylno;
  146.     xyp->xy_nblk  = label->dkl_map[sip->si_boff].dkl_nblk;
  147.  
  148.     xycmd(XY_INIT, sip, 0, 0, 0);
  149.  
  150.     /*
  151.      * Fetch bad block info.
  152.      */
  153.     xyp->xy_badaddr = ((int)xyp->xy_ncyl * xyp->xy_nhead - 1)
  154.               * xyp->xy_nsect;
  155.     if (xycmd(XY_READ, sip, xyp->xy_badaddr, (char *)&xyp->xy_bad, 1))
  156.         printf("xy: no bad block info\n");
  157.     return (0);
  158. }
  159.  
  160. xystrategy(sip, rw)
  161.     struct saioreq *sip;
  162.     int rw;
  163. {
  164.     register int cmd = (rw == WRITE) ? XY_WRITE : XY_READ;
  165.     register int boff;
  166.     register struct xyparam *xyp = (struct xyparam *)sip->si_devdata;
  167.     register short nsect;
  168. #ifndef BOOTBLOCK
  169.     char *ma;
  170.     int i, bn;
  171. #endif BOOTBLOCK
  172.  
  173.     boff = CYL(xyp->xy_boff);
  174. #ifdef BOOTBLOCK
  175.     /* assert si_cc == DEV_BSIZE */
  176.     if (xycmd(cmd, sip, sip->si_bn + boff, sip->si_ma, 1))
  177.         return (-1);
  178.     return (sip->si_cc);
  179. #else BOOTBLOCK
  180.     nsect = sip->si_cc / DEV_BSIZE;
  181.     if (sip->si_bn + nsect > xyp->xy_nblk)
  182.         nsect = xyp->xy_nblk - sip->si_bn;
  183.     if (nsect == 0)
  184.         return (0);
  185.     if (xycmd(cmd, sip, sip->si_bn+boff, sip->si_ma, nsect) == 0)
  186.         return (nsect*DEV_BSIZE);
  187.     /*
  188.      * Large transfer failed, now do one at a time
  189.      */
  190.     bn = sip->si_bn + boff;
  191.     ma = sip->si_ma;
  192.     for (i = 0; i < nsect; i++) {
  193.         if (xycmd(cmd, sip, bn, ma, 1))
  194.             return (-1);
  195.         bn++;
  196.         ma += DEV_BSIZE;
  197.     }
  198.     return (nsect*DEV_BSIZE);
  199. #endif    BOOTBLOCK
  200. }
  201.  
  202. #ifndef BOOTBLOCK
  203. /*
  204.  * This routine is called from isspinning() as the test condition.
  205.  */
  206. int
  207. xyspin(sip, dummy)
  208.     struct saioreq *sip;
  209.     int dummy;
  210. {
  211.     register struct xyiopb *xy = &((struct xydma *)sip->si_dmaaddr)->xyiopb;
  212.  
  213.     (void) xycmd(XY_STATUS, sip, 0, (char *)0, 0);
  214.     return ((xy->xy_status & XY_READY) ? 0 : 1);
  215. }
  216. #endif !BOOTBLOCK
  217.  
  218. xycmd(cmd, sip, bno, buf, nsect)
  219.     int cmd;
  220.     struct saioreq *sip;
  221.     register int bno;
  222.     char *buf;
  223.     int nsect;
  224. {
  225.     register int i, t;
  226.     register struct xyparam *xyp = (struct xyparam *)sip->si_devdata;
  227.     register struct xyiopb *xy = &((struct xydma *)sip->si_dmaaddr)->xyiopb;
  228.     register struct xydevice *xyaddr = (struct xydevice *)sip->si_devaddr;
  229.     register char *bp = ((struct xydma *)sip->si_dmaaddr)->xyblock;
  230.     unsigned short cylno, sect, head;
  231.     int error, errcnt = 0;
  232.  
  233.     cylno = bno / CYL(1);
  234.     sect = bno % xyp->xy_nsect;
  235.     head = (bno / xyp->xy_nsect) % xyp->xy_nhead;
  236.  
  237.     if (cmd == XY_WRITE && buf != bp)    /* Many just use common buf */
  238.         bcopy(buf, bp, nsect*DEV_BSIZE);
  239.  
  240. retry:
  241.     bzero((char *)xy, sizeof (struct xyiopb));
  242.     xy->xy_reloc = 1;
  243.     xy->xy_autoup = 1;
  244.     xy->xy_cmd = cmd >> 8;
  245.     xy->xy_drive = xyp->xy_drive;
  246.     xy->xy_unit = xyp->xy_unit & 3;
  247.     xy->xy_eccmode = 2;    /* means 0 on 440 */
  248.     xy->xy_throttle = XY_THROTTLE;
  249.  
  250.     switch (cmd) {
  251.         case XY_INIT:
  252.         xy->xy_head = xyp->xy_nhead - 1;
  253.         xy->xy_cylinder = xyp->xy_ncyl - 1;
  254.         xy->xy_sector = xyp->xy_nsect - 1;
  255.         break;
  256.         
  257.         default:
  258.         xy->xy_sector = sect;
  259.         xy->xy_head = head;
  260.         xy->xy_cylinder = cylno;
  261.         xy->xy_nsect = nsect;
  262.         xy->xy_bufoff = XYOFF(MB_DMA_ADDR(bp));
  263.         xy->xy_bufrel = XYREL(xyaddr, MB_DMA_ADDR(bp));
  264.         break;
  265.     }
  266.  
  267.     t = XYREL(xyaddr, MB_DMA_ADDR(xy));
  268.     xyaddr->xy_iopbrel[0] = t >> 8;
  269.     xyaddr->xy_iopbrel[1] = t;
  270.     xyaddr->xy_iopboff[0] = MB_DMA_ADDR(xy) >> 8;
  271.     xyaddr->xy_iopboff[1] = MB_DMA_ADDR(xy);
  272.     xyaddr->xy_csr = XY_GO;
  273.  
  274.     do {
  275.         DELAY(30);
  276.     } while (xyaddr->xy_csr & XY_BUSY);
  277.  
  278.     if (xyaddr->xy_csr & XY_ERROR) {
  279.         xyaddr->xy_csr = XY_ERROR;
  280.         DELAY(100);
  281.         xy->xy_iserr = 1;
  282.     }
  283.     if (xy->xy_iserr && xy->xy_errno != XYE_FECC) {
  284.         if (nsect != 1)        /* only try hard on single sectors */
  285.             return (-1);
  286.         error = xy->xy_errno;
  287.         if ((i = xyfwd(xyp, cylno, head, sect)) != 0)
  288.             return xycmd(cmd, sip, i, buf, 1);
  289.         /* Attempt to reset the error condition */
  290.         if (cmd != XY_RESTORE)
  291.             (void) xycmd(XY_RESTORE, sip, 0, (char *)0, 0);
  292.         if (++errcnt < 5)
  293.             goto retry;
  294.         if (bno != 0 || error != 5)    /* drive type probe */
  295.             printf("xy: error %x bno %d\n", error, bno);
  296.         return (-1);            /* Error */
  297.     }
  298.  
  299.     if (cmd == XY_READ && buf != bp)    /* Many just use common buf */
  300.         bcopy(bp, buf, nsect*DEV_BSIZE);
  301.  
  302.     return (0);
  303. }
  304.  
  305. xyfwd(xyp, cn, tn, sn)
  306.     register struct xyparam *xyp;
  307.     int cn, tn, sn;
  308. {
  309.     register struct dkbad *bt = &xyp->xy_bad;
  310.     register int i;
  311.  
  312.     if (bt->bt_mbz != 0)    /* not initialized */
  313.         return (0);
  314.     for (i=0; i<126; i++)        /* FIXME constant */
  315.         if (bt->bt_bad[i].bt_cyl == cn &&
  316.             bt->bt_bad[i].bt_trksec == (tn<<8)+sn) {
  317.             return (xyp->xy_badaddr - i - 1);
  318.         }
  319.     return (0);
  320. }
  321. #endif M25
  322.  
  323.